#ifndef LIST_H
#define LIST_H

#include "utility/Types.h"

/// @brief this is like id card
typedef struct ListNode {
    struct ListNode* next;
    struct ListNode* prev;
} ListNodeType;


typedef struct List {
    ListNodeType* head;
    ListNodeType* tail;
    int count;
} ListType;


void InitList(ListType* list);
void InitNode(ListNodeType* node);
void InsertNodeAtBegin(ListType* list, ListNodeType* node);
void InsertNodeAtEnd(ListType* list, ListNodeType* node);
ListNodeType* RemoveFirstNode(ListType* list);
ListNodeType* RemoveLastNode(ListType* list);
ListNodeType* RemoveNode(ListType* list, ListNodeType* node);

static inline ListNodeType* GetFirstNode(ListType* list)
{
    return list->head;
}
static inline ListNodeType* GetLastNode(ListType* list)
{
    return list->tail;
}
static inline IsListEmpty(ListType* list)
{
    return list->count == 0;
}
static inline GetListCount(ListType* list)
{
    return list->count;
}


#define NodeOffsetToParent(type, member)    ((uint32_t)&(((type*)0)->member))
#define GetNodeParentAddress(node, type, member)    ((uint32_t)node - NodeOffsetToParent(type, member))
#define NodeParent(node, type, member)   ((type*)(node? GetNodeParentAddress(node, type, member):0))



#endif